package com.hippo.core.util;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 字符串替换工具类
 *
 * @author zhuzhanhao
 */
@Slf4j
public class StringTools {

    public static boolean isNullOrEmpty(String str) {
        return null == str || "".equals(str) || "null".equals(str);
    }

    public static boolean isNullOrEmpty(Object obj) {
        return null == obj || "".equals(obj);
    }

    /**
     * 字符串正则替换
     *
     * @param str           需要替换的字符串
     * @param variableValue 正则表达式
     * @param actualValue   实际替换成的值
     * @return 替换完成的字符串
     */
    public static String replaceString(String str, String variableValue, String actualValue) {
        Pattern p = Pattern.compile(variableValue);
        Matcher m = p.matcher(str);
        return m.replaceAll(Matcher.quoteReplacement(actualValue));
    }

    /**
     * 获取当前的字符串中满足正则的字符串，将他们放入List
     *
     * @param str        内容字符串
     * @param expression 正则表达式
     * @return 满足正则匹配的 所有字符串的List
     */
    public static List<String> getStringList(String str, String expression) {
        List<String> strList = new ArrayList<String>();
        Pattern p = Pattern.compile(expression);
        Matcher m = p.matcher(str);
        while (m.find()) {
            String string = m.group().toString().substring(2, m.group().toString().length() - 1);
            if(!strList.contains(string)){
                strList.add(string);
            }
        }
        return strList;
    }

    /**
     * 替换数组中满足正则的变量
     *
     * @param prefix     前缀
     * @param suffix     后缀
     * @param jsonArray  需要替换的数组
     * @param jsonObject 实际替换值的对象
     * @return 替换后的数组
     */
    public static JSONArray replaceArray(String prefix, String suffix, JSONArray jsonArray, List<JSONObject> jsonObject) {
        if (jsonObject.size() > 0) {
            if (prefix.contains("[")) {
                log.info("存在元素表达式变量：" + jsonObject.toString());
            } else {
                log.info("存在用例变量：" + jsonObject.toString());
            }
            for (int i = 0; i < jsonObject.size(); i++) {
                jsonArray = JSONArray.parseArray(replaceString(jsonArray.toString(), prefix + jsonObject.get(i).getString("name") + suffix, jsonObject.get(i).getString("value").replace("\"", "'")));
            }
        }
        return jsonArray;
    }

    /**
     * 重载replaceArray方法，加入fieldList参数，替换数组中满足正则的变量
     *
     * @param prefix     前缀
     * @param suffix     后缀
     * @param jsonArray  需要替换的数组
     * @param fieldList  字段列表
     * @param jsonObject 实际替换值的对象
     * @return 替换后的数组
     */
    public static JSONArray replaceArray(String prefix, String suffix, JSONArray jsonArray, ArrayList<String> fieldList, Map<String, String> jsonObject) {
        String str = jsonArray.toString();
        for (int i = 0; i < fieldList.size(); i++) {
            str = replaceString(str, prefix + fieldList.get(i) + suffix, jsonObject.get(fieldList.get(i)));
        }
        return JSONArray.parseArray(str);
    }

    /**
     * 递归获取当前数组中所有的caseId
     *
     * @param caseIdJSONArray 新的caseId数组
     * @param steps           原数组
     * @return caseIdJSONArray
     */
    public static JSONArray caseIdRecursion(JSONArray caseIdJSONArray, JSONArray steps) {
        for (int i = 0; i < steps.size(); i++) {
            JSONObject jsonObject = JSONObject.parseObject(com.alibaba.fastjson.JSON.toJSONString(steps.get(i)));
            String caseId = jsonObject.getString("caseId");
            if (caseId != null & !caseIdJSONArray.contains(caseId) & jsonObject.getJSONArray("children").size() != 0) {
                caseIdJSONArray.add(caseId);
            }
        }
        for (int i = 0; i < steps.size(); i++) {
            JSONObject jsonObject = JSONObject.parseObject(com.alibaba.fastjson.JSON.toJSONString(steps.get(i)));
            JSONArray children = jsonObject.getJSONArray("children");
            if (children != null & children.size() > 0) {
                return caseIdRecursion(caseIdJSONArray, children);
            }
        }
        return caseIdJSONArray;
    }

    /**
     * 构造步骤执行的规则数据
     *
     * @param steps 原数组
     * @return 符合运行规则的数据
     */
    public static JSONArray getNewSteps(JSONArray steps) {
        JSONArray newSteps = new JSONArray();
        steps.forEach(item -> {
            JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(item));
            ArrayList<String> elList = new ArrayList<>();
            ArrayList<String> dataList = new ArrayList<>();
            if (jsonObject.getJSONObject("optElement").getString("by") != null & !jsonObject.getJSONObject("optElement").getString("by").equals("")) {
                elList.add(jsonObject.getJSONObject("optElement").getString("by"));
            }
            if (jsonObject.getJSONObject("optElement").getString("expression") != null & !jsonObject.getJSONObject("optElement").getString("expression").equals("")) {
                elList.add(jsonObject.getJSONObject("optElement").getString("expression"));
            }
            JSONArray optData = jsonObject.getJSONArray("optData");
            if (optData.size() > 0) {
                for (int i = 0; i < optData.size(); i++) {
                    dataList.add(JSONObject.parseObject(optData.get(i).toString()).getString("value"));
                }
            }
            jsonObject.put("optElement", elList);
            jsonObject.put("optData", dataList);
            newSteps.add(jsonObject);
        });
        return newSteps;
    }

    private static List<JSONObject> getChildren(JSONObject jsonObject) {
        return jsonObject.getJSONArray("children").toJavaList(com.alibaba.fastjson.JSONObject.class)
                .stream()
                .flatMap(ob -> Stream.concat(getChildren(ob).stream(), Stream.of(ob)))
                .collect(Collectors.toList());
    }

    /**
     * 递归扁平化树结构数据
     *
     * @param jsonArray 元数组
     * @return 扁平化的数组
     */
    public static JSONArray stepRecursion(JSONArray jsonArray) {
        List<JSONObject> list = jsonArray.toJavaList(com.alibaba.fastjson.JSONObject.class).stream()
                .flatMap(ob -> Stream.concat(getChildren(ob).stream(), Stream.of(ob)))
                .filter(jsonObject -> jsonObject.getJSONArray("children").size() == 0)//此时还是jsonObject
                .collect(Collectors.toList());
        return JSONArray.parseArray(JSON.toJSONString(list));
    }
}

